package org.hbhk.hxl.gateway.boot;

import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hbhk.hxl.gateway.exception.GlobalExceptionHandler;
import org.hbhk.hxl.gateway.redis.RedisUtil;
import org.hbhk.hxl.gateway.route.TimeoutNettyRoutingFilter;
import org.hbhk.hxl.gateway.services.ServiceUtil;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.gateway.config.HttpClientProperties;
import org.springframework.cloud.gateway.filter.factory.StripPrefixGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.result.view.ViewResolver;

import reactor.netty.http.client.HttpClient;

@Configuration
public class GatewayBootConfiguration implements InitializingBean {

	private final Logger log = LoggerFactory.getLogger(GatewayBootConfiguration.class);

	@Value("${server.port:8080}")
	private String port;

	@Bean
	@LoadBalanced
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}

//	@Bean
//	public GatewayLoadBalancerClientFilter userLoadBalanceClientFilter(LoadBalancerClient client,
//			LoadBalancerProperties properties) {
//		return new GatewayLoadBalancerClientFilter(client, properties);
//	}

	@Primary
	@Bean
	@Order(Ordered.HIGHEST_PRECEDENCE)
	public ErrorWebExceptionHandler errorWebExceptionHandler(ObjectProvider<List<ViewResolver>> viewResolversProvider,
			ServerCodecConfigurer serverCodecConfigurer) {

		GlobalExceptionHandler jsonExceptionHandler = new GlobalExceptionHandler();
		jsonExceptionHandler.setViewResolvers(viewResolversProvider.getIfAvailable(Collections::emptyList));
		jsonExceptionHandler.setMessageWriters(serverCodecConfigurer.getWriters());
		jsonExceptionHandler.setMessageReaders(serverCodecConfigurer.getReaders());
		return jsonExceptionHandler;
	}

	@Bean
	public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
		StripPrefixGatewayFilterFactory.Config config = new StripPrefixGatewayFilterFactory.Config();
		config.setParts(1);
		// http://10.10.0.60:8080/galaxy-user-business/static/app/common/healthCheck
		String uri = "http://127.0.0.1:" + port + "/";
		RouteLocator routeLocator = builder.routes().route("host_route", r -> r.path("/**").uri(uri)).build();
		return routeLocator;
	}

	@Bean
	public TimeoutNettyRoutingFilter routingTimeoutFilter(HttpClient httpClient,
			ObjectProvider<List<HttpHeadersFilter>> headersFilters, HttpClientProperties properties) {
		return new TimeoutNettyRoutingFilter(httpClient, headersFilters, properties);
	}

	//
//10.206.36.33:6379,10.206.36.33:6380,10.206.36.33:6381,10.206.36.33:6382,10.206.36.33:6383,10.206.36.33:6384
	@Value("${redis.addr}")
	private String redisAddr = "";
	@Value("${redis.pwd}")
	private String setPassword = "";

	@Bean
	public RedissonClient redissonClient() {
		try {
//			String redis = System.getProperty("redis.open");
//			if (StringUtils.isEmpty(redis)) {
//				return null;
//			}
			Config config = new Config();
			String[] addrArr = redisAddr.split(",");
			if (addrArr.length > 1) {
				ClusterServersConfig serversConfig = config.useClusterServers().setScanInterval(2000);
				if (StringUtils.isNotEmpty(setPassword)) {
					serversConfig.setPassword(setPassword);

				}
				for (int i = 0; i < addrArr.length; i++) {
					serversConfig.addNodeAddress("redis://" + addrArr[i]);
				}

			} else {
				SingleServerConfig serversConfig = config.useSingleServer().setAddress("redis://" + redisAddr);
				if (StringUtils.isNotEmpty(setPassword)) {
					serversConfig.setPassword(setPassword);

				}
			}
			RedissonClient redisson = Redisson.create(config);
			return redisson;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

	}

	@Bean
	public ServiceUtil getServiceUtil() {

		ServiceUtil serviceUtil = new ServiceUtil();
		return serviceUtil;

	}

	@Override
	public void afterPropertiesSet() throws Exception {
		RedisUtil.put("name", "hbhk");
		log.error("启动端口号:" + port);

	}

}
